package cn.iocoder.devlop.module.annual.report.interceptor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.devlop.module.annual.report.annotations.SyncField;
import cn.iocoder.devlop.module.annual.report.annotations.SyncTable;
import com.alibaba.ttl.threadpool.agent.internal.javassist.bytecode.analysis.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

@Intercepts(
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
)
public class SyncInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

//      1.解析获取标有指定注解的类
        Set<String> tables = new HashSet<>();
        HashMap<String, String[]> stringHashMap = new HashMap<>();

        //获取方法参数
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameter = invocation.getArgs()[1];

        // 判断是否满足拦截条件
        if (mappedStatement != null && mappedStatement.getId() != null &&
                (mappedStatement.getId().contains("update") || mappedStatement.getId().contains("insert")) && parameter != null) {
            // 获取被拦截方法上的注解信息
            Method method = mappedStatement.getClass().getMethod("getMethod");
            Annotation[] annotations = method.getAnnotations();
//
            // 遍历注解信息，寻找特定的注解
            for (Annotation annotation : annotations) {
                if (annotation.annotationType() == SyncTable.class) {
                    SyncTable synctable = (SyncTable) annotation;
                    //2.根据注解属性条件判断数据是否需要处理,根据fieldName和havingValue是否需要处理
                    String havingValue = synctable.havingValue();
                    String fieldName = synctable.fieldName();
                    String property = (String)BeanUtil.getProperty(parameter, fieldName);
                    if (!StrUtil.hasEmpty(synctable.havingValue(),synctable.fieldName()) && property.equals(havingValue)){
                        // 获取方法的参数类型
                        Class<?> parameterType = parameter.getClass();
                        // 获取参数类型的字段信息
                        Field[] fields = parameterType.getDeclaredFields();
                        // 遍历字段信息，寻找标记有 SyncField 注解的字段
                        for (Field field : fields) {
                            if (field.isAnnotationPresent(SyncField.class)) {
                                SyncField syncField = field.getAnnotation(SyncField.class);
                                // 获取 SyncField 注解的属性值
                                String fieldValue = syncField.value();
                                // 处理标记有 SyncField 注解的字段
                                // 这里可以根据需要执行相关的逻辑
                            }
                        }

                    }
                    break;
                }
            }
        }

        // 继续执行原始方法
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Interceptor.super.plugin(target);
    }

    @Override
    public void setProperties(Properties properties) {
        Interceptor.super.setProperties(properties);
    }





        //1.解析获取标有指定注解的类
        //2.根据注解属性条件判断数据是否需要处理,根据fieldName和havingValue是否需要处理
        //3.根据表注解以及字段注解生成配置集合
        // set保存所有需要同步的表名 获取tables将其转换为set集合再add.value
        // 生成表需保存字段时将ignoreTableName标注的所有字段忽略 判断依据为set表名是否存在 数据格式 map=>tableName,filed(,)
        //4.根据配置集合获取实体属性
        //5.根据配集合保存数据(先进行拼接sql)


}
